#!/usr/bin/python -O

import sys, os, shutil
import stat
import subprocess
import datetime

from dbcli import VerticaCli

def cmistop():
    print '\nStoping old instance ...'
    subprocess.call(['cmistop'])


def backup(vsql, sphome, backupdir, schema_, suffix, install, instances):
    print '\nBacking up configuration files, repository ...'
    shutil.rmtree(backupdir, ignore_errors=True)
    os.makedirs(backupdir)

    # backup configration files
    shutil.copy(sphome + '/base/source/etc/seapilot.conf', backupdir)
    shutil.copytree(sphome + '/base/source/etc/cmi', backupdir + '/cmi')
    shutil.copy(sphome + '/web/etc/hpdsm_config.xml', backupdir)

    vsql.execute(['\\o %s/reports' % backupdir,
        'select * from %s.configuration_report_definitions_table' % schema_,
        '\\o'])

    #backup schema
    if install:
        vsql.execute(['alter schema %s rename to sp_%s' % (schema_, suffix)])


def restore_config(sphome, backupdir):
    print '\nRestoring config files ...'

    # restore configration files
    shutil.copy(backupdir + '/seapilot.conf', sphome + '/base/source/etc')
    shutil.rmtree(sphome + '/base/source/etc/cmi', ignore_errors=True)
    shutil.copytree(backupdir + '/cmi', sphome + '/base/source/etc/cmi')


def restore_reports(vsql, schema_, suffix):
    print '\nRestoring reports ...'

    # restore reports
    report_table = 'configuration_report_definitions_table'
    vsql.execute(['insert into %s.%s select * from sp_%s.%s'
                      % (schema_, report_table, suffix, report_table),
                  'commit'])


def install_pkg(sphome, suffix, pkgfile):
    print '\nRemoving old instance and install the new one ...'
    os.rename(sphome, '.'.join([sphome, suffix]))

    args = ['tar', 'xzf', pkgfile]
    print '   ', args
    subprocess.call(args)


def init_db(sphome, db_, schema_, uid_, pass_):
    print '\nInitializing repository ...'
    os.environ['SP_REPOS_SCHEMA_NAME'] = schema_
    args = [sphome + '/scripts/setreposschema', schema_]
    subprocess.call(args)

    cmd = sphome + '/mi/vertica/repository/scripts/InstanceRepositoryInstall'
    args = [cmd, '-d', db_, '-s', schema_, '-u', uid_, '-p', pass_]
    print '   ', args
    subprocess.call(args)


def register_dsi(vsql, schema_, instances_):
    print '\nRegistering DSI ...'
    cmdlist = ['set search_path = ' + schema_]
    for inst in instances_:
        cmdlist.append("insert into configuration_instance_table values"
                       + " (%(id)d, '%(name)s', '%(type)s'," % inst
                       + " '%(description)s', %(contact_id)s," % inst
                       + " '%(timezone)s', %(time_format_enum)d)" % inst)
        cmdlist.append("insert into %s.dimension_instance_table values"
                       % schema_
                       + " (%(id)d, 0, 0, 0)" % inst)

    cmdlist.append('commit')
    vsql.execute(cmdlist)


def install_tna(instances_, sphome, db_, schema_):
    print '\nInstalling TNA ...'
    for inst in instances:
        cmd = ' '.join(['%s/base/scripts/tna_start.sh' % sphome,
                        '-d %s -s %s' % (db_, schema_),
                        '-u seapilot -p seapilot1',
                        '-f %s/base/vertica/bin64/topn_analyzer' % sphome,
                        '-i %(id)d' % inst,
                        '-m install'])
        print '   ', cmd
        subprocess.call(cmd, shell=True)


def install_hpdsm(sphome, backupdir):
    print '\nInstalling hpdsm ...'
    args = ['sudo',
            'cp', '%s/web/hpdsm/target/hpdsm.war' % sphome,
            '/opt/home/jetty/webapps']
    print '   ', args
    subprocess.call(args)
    shutil.copy(backupdir + '/hpdsm_config.xml', sphome + '/web/etc')


# ------ main  ------------
from optparse import OptionParser

parser = OptionParser()
parser.add_option('--sphome', dest='sphome',
        action='store', default='spbronto',
        help='in which directory to install seapilot, default [%default]')
parser.add_option('--pkg-file', dest='file',
        action='store',
        help='package file, default [%default]')
parser.add_option('--install', dest='install',
        action='store_true', default=False,
        help='whether a new install, default [%default]')

(opts, args) = parser.parse_args()

if opts.file is None:
    print '--pkg-file could not be empty'
    sys.exit(1)

instances = [{'id': 168,
              'name': 'Bronto-Cmi-Sq168',
              'type': 'VERTICA',
              'description': 'SQ 168 CMI for the bronto cluster',
              'contact_id': 'NULL',
              'timezone': 'Etc/UTC',
              'time_format_enum': 1
              },
             {'id': 169,
                 'name': 'Seaquest-Dsi-Sq169',
                 'type': 'SEAQUEST',
                 'description': 'SQ 169 Seaquest DSI for the bronto cluster',
                 'contact_id': 'NULL',
                 'timezone': 'Etc/UTC',
                 'time_format_enum': 1
              }]

database, schema   = 'vertica',  'seapilot'
uid,      password = 'seapilot', 'seapilot1'

datestr   = datetime.datetime.now().strftime('%m%d')
backupdir = 'sp_bak' + '/' + datestr

cmistop()
vsql = VerticaCli(uid=uid, passwd=password)

try:
    backup(vsql, opts.sphome, backupdir, schema, datestr, opts.install, instances)

    install_pkg(opts.sphome, datestr, opts.file)

    restore_config(opts.sphome, backupdir)

    if opts.install:
        init_db(opts.sphome, database, schema, uid, password)
        register_dsi(vsql, schema, instances)
        restore_reports(vsql, schema_, suffix)

    install_hpdsm(opts.sphome, backupdir)

finally:
    vsql.close()
